<?php


namespace App\Bus;

use App\Businesses\BusinessState;
use App\Exceptions\ServiceException;
use App\Services\Base\Interfaces\ConfigServiceInterface;
use App\Services\Base\Services\ConfigService;
use Carbon\Carbon;
use App\Events\UserLoginEvent;
use App\Constant\FrontendConstant;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use App\Services\Member\Services\UserService;
use App\Services\Member\Services\SocialiteService;
use App\Services\Member\Interfaces\UserServiceInterface;
use App\Services\Member\Interfaces\SocialiteServiceInterface;

use Illuminate\Support\Facades\Log;


class AuthBus
{
    public const ERROR_CODE_BIND_MOBILE = -100;
    /**
     * @var SocialiteService
     */
    protected $socialiteService;

    /**
     * @var UserService
     */
    protected $userService;

    /**
     * @var ConfigService
     */
    protected $configService;



    public function __construct(
        SocialiteServiceInterface    $socialiteService,
        UserServiceInterface         $userService,
        ConfigServiceInterface       $configService

    )
    {
        $this->socialiteService = $socialiteService;
        $this->userService = $userService;
        $this->configService = $configService;

    }

    public function tokenLogin(int $userId, string $platform)
    {
        $loginAt = Carbon::now();

        $token = Auth::guard('apiv2')
            ->claims([
                FrontendConstant::USER_LOGIN_AT_COOKIE_NAME => $loginAt->timestamp,
            ])
            ->tokenById($userId);

        event(new UserLoginEvent($userId, $platform, $loginAt->toDateTimeLocalString()));

        return $token;
    }


    /**
     * 初次登录
     * @param string $openId
     * @param string $unionId
     * @param $data
     * @return int
     */
    public function douyinLogin(string $openId, string $unionId, $data): int
    {


        //这里查是否是已经有unionid，如果有找到 就返回
        if ($unionId && $socialiteRecord = $this->socialiteService->findUnionId($unionId)) {
            return $socialiteRecord['user_id'];
        }
        // 如果没有unionid及openid 则会创建新的用户
        $data = [
            'nickname' => $data['nick_name'] ?? '',
            'avatar' => $data['avatar'] ?? '',
        ];

        return $this->socialiteService->bindAppWithNewUser(FrontendConstant::DOUYIN_LOGIN_SIGN, $openId, $data, $unionId);
    }


    public function wechatLogin(string $openId, string $unionId, $data): int
    {


        //这里查是否是已经有unionid，如果有找到 就返回
        if ($unionId && $socialiteRecord = $this->socialiteService->findUnionId($unionId)) {
            return $socialiteRecord['user_id'];
        }
//这里查是否是已经有openid，如果有找到 就返回

        $socialiteRecord = $this->socialiteService->findBind(FrontendConstant::WECHAT_LOGIN_SIGN, $openId);
        // 为什么这里判断下unionId，因为第一次没有 可能加入开放平台就有权限了  这里就可能有unionId了
        if ($socialiteRecord) {
            // 更新unionId
            $unionId && $this->socialiteService->updateUnionId($socialiteRecord['id'], $unionId);

            return $socialiteRecord['user_id'];
        }
        // 如果没有unionid及openid 则会创建新的用户
        $data = [
            'nickname' => $data['nickname'] ?? '',
            'avatar' => $data['headimgurl'] ?? '',
        ];

        return $this->socialiteService->bindAppWithNewUser(FrontendConstant::WECHAT_LOGIN_SIGN, $openId, $data, $unionId);
    }

    public function wechatMiniLogin(string $openId, string $unionId)
    {


        if ($unionId && $socialiteRecord = $this->socialiteService->findUnionId($unionId)) {
            return $socialiteRecord['user_id'];
        }
        $socialiteRecord = $this->socialiteService->findBind(FrontendConstant::WECHAT_MINI_LOGIN_SIGN, $openId);
        if ($socialiteRecord) {
            // 更新unionId
            $unionId && $this->socialiteService->updateUnionId($socialiteRecord['id'], $unionId);
            return $socialiteRecord['user_id'];
        }

        return 0;
    }

    public function douyinMiniLogin(string $openId, string $unionId)
    {


        if ($unionId && $socialiteRecord = $this->socialiteService->findUnionId($unionId)) {
            return $socialiteRecord['user_id'];
        }
        return 0;
    }


    public function wechatMiniMobileLogin(string $openId, string $unionId, string $mobile,  $data)
    {

        //如果有unionid则直接返回登录
        if ($unionId && $socialiteRecord = $this->socialiteService->findUnionId($unionId)) {

            return $socialiteRecord['user_id'];
        }

        //验证是否用手机号登录过，如果之前有就绑定，如果没有的话就创建一条
        $user = $this->userService->findMobile($mobile);

        if (!$user) {
            $user = $this->userService->createWithMobile($mobile,'', $data['nickName']??'', $data['avatarUrl']??'');
        }

        $this->socialiteService->bindApp($user['id'], FrontendConstant::WECHAT_MINI_LOGIN_SIGN, $openId, $data, $unionId);

        return $user['id'];



    }

    public function douyinMiniMobileLogin(string $openId, string $unionId, string $mobile, string $corpId, $data)
    {

        //如果有unionid则直接登录
        if ($unionId && $socialiteRecord = $this->socialiteService->findUnionId($unionId)) {
            return $socialiteRecord['user_id'];
        }

        //验证是否用手机号登录过
        $user = $this->userService->findMobile($mobile);

        if (!$user) {
            $user = $this->userService->createWithMobile($mobile, '', $data['nickName']??'', $data['avatarUrl']??'');
        }

        $this->socialiteService->bindApp($user['id'], FrontendConstant::DOUYIN_LOGIN_SIGN, $openId, $data, $unionId);

        return $user['id'];



    }


    public function registerWithSocialite(
        string $mobile,
        string $app,
        string $appId,
        string $unionId,
        string $nickname,
        string $avatar,
        array  $data
    )
    {
        return DB::transaction(function () use ($mobile, $app, $appId, $unionId, $nickname, $avatar, $data) {
            $user = $this->userService->findMobile($mobile);
            if ($user) {
                throw new ServiceException(__('手机号已存在'));
            }

            /**
             * @var BusinessState $bus
             */
            $bus = app()->make(BusinessState::class);
            $bus->socialiteBindCheck(0, $app, $appId);

            // 创建用户
            $user = $this->userService->createWithMobile($mobile, '', $nickname, $avatar);

            $this->socialiteService->bindApp($user['id'], $app, $appId, $data, $unionId);

            return $user['id'];
        });
    }


}
